package com.hyphenate.easeim.common.db

import android.util.Log
import com.hyphenate.EMValueCallBack
import com.hyphenate.chat.EMClient
import com.hyphenate.chat.EMUserInfo
import com.hyphenate.easeim.common.db.dao.EmUserDao
import com.hyphenate.easeim.common.db.entity.EmUserEntity
import com.hyphenate.easeui.domain.EaseUser
import com.salton123.log.XLog
import java.util.HashMap

/**
 * @Time:2021/5/6 11:31
 * @Author:wujinsheng
 * @Description:
 */
object UserRepository : EmUserDao by DemoDbHelper.getInstance().userDao {
    const val TAG = "UserRepository"
    fun updateContactList(contactList: List<EaseUser?>?): Boolean {
        val userEntities = EmUserEntity.parseList(contactList)
        insert(userEntities)
        return true
    }

    val contactList: Map<String, EaseUser>
        get() {
            val map: MutableMap<String, EaseUser> = HashMap()
            val users = loadAllEaseUsers()
            if (users.isNotEmpty()) {
                for (user in users) {
                    map[user.username] = user
                }
            }
            return map
        }

    val friendContactList: Map<String, EaseUser>
        get() {
            val map: MutableMap<String, EaseUser> = HashMap()
            val users = loadContacts()
            if (users.isNotEmpty()) {
                for (user in users) {
                    map[user.username] = user
                }
            }
            return map
        }

    /**
     * 判断是否是联系人
     *
     * @param userId
     * @return
     */
    fun isContact(userId: String): Boolean {
        val contactList = friendContactList
        return contactList.keys.contains(userId)
    }

    /**
     * 查找有关用户用户属性过期的用户ID
     */
    fun selectTimeOutUsers(userInfoTimeOut: Long): List<String> {
        return loadTimeOutEaseUsers(userInfoTimeOut, System.currentTimeMillis())
    }

    /**
     * 查找有关用户用户属性过期的用户ID
     */
    fun loadTimeOutFriendUser(userInfoTimeOut: Long): List<String> {
        return loadTimeOutFriendUser(userInfoTimeOut, System.currentTimeMillis())
    }

    fun getEaseUsers(usernames: MutableList<String>, callback: EMValueCallBack<List<EaseUser>>?) {
        val cacheUsers = loadEaseUsersByIds(usernames.toTypedArray())
        if (cacheUsers.size < usernames.size) {
            val finalUsers: MutableList<EaseUser> = mutableListOf()
            finalUsers.addAll(cacheUsers)
            usernames.forEach { name ->
                if (cacheUsers.find { it.username == name } == null) {
                    finalUsers.add(EaseUser(name))
                }
            }
            callback?.onSuccess(cacheUsers)
        } else {
            callback?.onSuccess(cacheUsers)
        }
    }

    /**
     * 远端拉取用户信息，并且入库
     */
    @JvmOverloads
    fun saveUserInfo(
        userId: String,
        callback: EMValueCallBack<EMUserInfo>? = null
    ) {
        saveUserInfo(mutableListOf(userId), object : EMValueCallBack<Map<String, EMUserInfo>> {
            override fun onSuccess(value: Map<String, EMUserInfo>?) {
                if (value.isNullOrEmpty()) {
                    callback?.onError(-1, "can not find user")
                }
            }

            override fun onError(error: Int, errorMsg: String?) {
                callback?.onError(error, errorMsg)
            }
        })
    }


    /**
     * 远端拉取用户信息，并且入库
     */
    @JvmOverloads
    fun saveUserInfo(
        userIds: MutableList<String>,
        callback: EMValueCallBack<Map<String, EMUserInfo>>? = null
    ) {
        EMClient.getInstance().userInfoManager().fetchUserInfoByUserId(
            userIds.toTypedArray(),
            object : EMValueCallBack<Map<String,
                EMUserInfo>> {
                override fun onSuccess(value: Map<String, EMUserInfo>?) {
                    callback?.onSuccess(value)
                    val userInfos = parseUserInfo(value)
                    saveUsers(userInfos)
                }

                override fun onError(error: Int, errorMsg: String?) {
                    callback?.onError(error, errorMsg)
                }
            })
    }

    private fun parseUserInfo(userInfos: Map<String, EMUserInfo>?): List<EaseUser> {
        val users: MutableList<EaseUser> = mutableListOf()
        userInfos?.apply {
            map { it.value }.forEach { info ->
                var user = EaseUser(info.userId)
                user.nickname = info.nickName
                user.avatar = info.avatarUrl
                user.email = info.email
                user.gender = info.gender
                user.birth = info.birth
                user.sign = info.signature
                user.ext = info.ext
                users.add(user)
            }
        }
        return users
    }

    fun saveUsers(contactList: List<EaseUser>) {
        for (entity in contactList) {
            addUserToDB(entity)
        }
    }

    private fun addUserToDB(user: EaseUser) {
        val dbUser = loadUser(user.nickname)
        if (dbUser == null) {
            val ret = insert(EmUserEntity.parseParent(user))
            XLog.i(TAG, "saveOrUpdateUser ret:$ret")
        } else {
            XLog.i(TAG, "dbUser exist")
        }
    }

    private fun updateUserToDB(user: EaseUser) {
        loadUser(user.nickname)?.let {
            user.contact = it.contact
            val ret = insert(EmUserEntity.parseParent(user))
            Log.i(TAG, "saveOrUpdateUser ret:$ret")
        } ?: kotlin.run { addUserToDB(user) }
    }
}

